package com.byzk.p2p.admin.order.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.byzk.p2p.admin.base.util.BaseUtil;
import com.byzk.p2p.admin.base.util.CopyEntity;
import com.byzk.p2p.admin.base.util.PageInfo;
import com.byzk.p2p.admin.borrow.dao.BorrowDao;
import com.byzk.p2p.admin.borrow.dao.BorrowGroupUserDao;
import com.byzk.p2p.admin.borrow.dto.Borrow;
import com.byzk.p2p.admin.borrow.dto.UserTender;
import com.byzk.p2p.admin.borrow.service.TenderService;
import com.byzk.p2p.admin.borrow.util.BorrowStatus;
import com.byzk.p2p.admin.borrow.vo.BorrowApplyVo;
import com.byzk.p2p.admin.order.dao.TenderAutoDao;
import com.byzk.p2p.admin.order.dao.TenderOrderDao;
import com.byzk.p2p.admin.order.dto.TenderAuto;
import com.byzk.p2p.admin.order.dto.TenderOrder;
import com.byzk.p2p.admin.order.vo.TenderAutoVo;
import com.byzk.p2p.admin.order.vo.TenderOrderVo;
import com.byzk.p2p.admin.score.dto.ScoreRecord;
import com.byzk.p2p.admin.score.service.ScoreRecordService;
import com.byzk.p2p.admin.system.dto.MemberLevel;
import com.byzk.p2p.admin.system.dto.SystemConfig;
import com.byzk.p2p.admin.system.service.MemberService;
import com.byzk.p2p.admin.system.service.SystemService;
import com.byzk.p2p.admin.user.dao.UserAccountDao;
import com.byzk.p2p.admin.user.dao.UserDao;
import com.byzk.p2p.admin.user.dto.User;
import com.byzk.p2p.admin.user.dto.UserAccount;
import com.byzk.p2p.admin.user.service.UserAccountService;

@Service
public class OrderService {

	@Autowired
	private TenderOrderDao tenderOrderDao;
	@Autowired
	private TenderAutoDao tenderAutoDao;
	@Autowired
	private BorrowDao borrowDao;
	@Autowired
	private TenderService tenderService;
	@Autowired
	private UserAccountDao userAccountDao;
	@Autowired
	private BorrowGroupUserDao borrowGroupUserDao;
	@Autowired
	private UserDao userDao;
	@Autowired
	private UserAccountService userAccountService;
	@Autowired
	private SystemService systemService;
	@Autowired
	private MemberService memberService;
	@Autowired
	private ScoreRecordService scoreRecordService;
	
	/**
	 * 添加后修改自动投标设置
	 * 
	 * @param vo
	 * @throws Exception
	 */
	public void saveOrUpdate(TenderOrderVo vo) throws Exception {
		TenderAuto auto = new TenderAuto();
		CopyEntity.copy(vo,auto);
		if (auto.getId() == null) {
			Integer orderId = 0;
			Integer userId = vo.getUserId();
			// 判断用户是否存在排序
			TenderOrder order = tenderOrderDao.selectByUserId(userId);
			if (order == null) {
				order = new TenderOrder();
				order.setUserid(userId);
				// 默认关闭
				order.setStatus(TenderOrder.Status.CLOSE.index);
				order.setOrder(0);
				// 设置开启
/*				if (vo.getStatus() == TenderOrder.Status.START.index) {
					order.setStart(TenderOrder.Status.START.index);
					Integer lastId = tenderOrderDao.lastId();
					// 设置序号
					if (lastId != null) {
						order.setOrder(lastId + 1);
					} else {
						order.setOrder(1);
					}
				}*/
				// 新增用户自动投标记录
				orderId = tenderOrderDao.insert(order);
			} else {
				orderId = order.getId();
			}
			auto.setOrderId(order.getId());
			// 新增投标设置
			tenderAutoDao.insert(auto);
		} else {
			tenderAutoDao.update(auto);
		}
	}

	/**
	 * 修改自动投标记录（主要用于开启或关闭自动投标）
	 * 
	 * @param order
	 */
	public void updateOrder(TenderOrder order) {
		tenderOrderDao.update(order);
	}

	/**
	 * 查询自动投标设置列表
	 * 
	 * @param auto
	 * @return
	 */
	public PageInfo<TenderAutoVo> listAuto(TenderAutoVo auto) {
		int count = tenderAutoDao.count(auto);
		List<TenderAutoVo> voList = tenderAutoDao.list(auto);
		PageInfo<TenderAutoVo> page = new PageInfo<TenderAutoVo>(count, auto.getIndex(), auto.getLimit());
		page.setPageList(voList);
		return page;
	}
	
	/**
	 * 删除自动投标设置
	 * @param id
	 */
	public void deleteAuto(Integer id){
		tenderAutoDao.delete(id);
	}
	
	/**
	 * 查询自动投标记录列表
	 * @param order
	 * @return
	 */
	public PageInfo<TenderOrder> listAuto(TenderOrder order) {
		int count = tenderOrderDao.count(order);
		List<TenderOrder> voList = tenderOrderDao.list(order);
		PageInfo<TenderOrder> page = new PageInfo<TenderOrder>(count, order.getIndex(), order.getLimit());
		page.setPageList(voList);
		return page;
	}
	
	/**
	 * 查询当前用户排序
	 * @param userId
	 * @return
	 */
	public Integer rowno(Integer userId){
		TenderOrder order = new TenderOrder();
		order.setUserid(userId);
		List<TenderOrder> list = tenderOrderDao.rowno(order);
		if(list.size()==0){
			return 0;
		}else{
			return list.get(0).getRowno();
		}
	}

	/**
	 * 开始自动投标
	 * 可投借款标用户设定条件：
	 * 必须设置交易密码
	 * 设置最小年利率<=借款标年利率<=设置最大年利率
	 * 设置最小借款期限<=借款标年利率<=设置最大借款期限
	 * 还款方式：-1代表不限（可投任意还款方式的借款标），0代表一次性还款，1代表按月付息到期还本，2代表等额本息
	 * 账户可用余额-保留可用余额>=单次投标金额
	 * 可投借款标条件：
	 * 剩余可投金额>=设定的单次投标金额，不能投新手标，自己借款的标，设置了投资密码的标，不属于普通标组
	 * 当借款标最小投资金额大于0时 设置的投资金额需大于等于最小值
	 * 当借款标最大投资金额大于0时 设置的投资金额需小于等于最大值
	 * 注：每个设定自动条件的用户只能投一个标一次
	 * @param borrowId 借款标id
	 * @return
	 */
	public List<TenderAuto> autoStart(Integer borrowId){
		Borrow borrow = borrowDao.getBorrowById(borrowId);
		Double borrowAmount = borrow.getAmount();//借款金额
		Double notTenderMoney = borrow.getNotTenderMoney();//借款标剩余可投金额
		//是否新手标
		boolean isNewBorrow = borrow.getBorrowApplyId().equals(-1)?true:false;
		//是否设置投资密码
		boolean isSetTenderPwd = StringUtils.isNotBlank(borrow.getTenderPwd())?true:false;
		//是否非普通标组
		boolean isPrivateBorrowGroup = false;
		if (borrow.getBorrowGroupId() != null && borrowGroupUserDao.getBorrowGroupById(borrow.getBorrowGroupId()).getPrivateBorrow().equals("Y")) {
			isPrivateBorrowGroup = true;
		}
		//借款标是新手标，设置了投资密码的标，非普通标组，过期 直接返回
		if (isNewBorrow || isSetTenderPwd || isPrivateBorrowGroup || borrow.getStatus().equals(BorrowStatus.EXPIRE)) {
			return null;
		}
		Integer borrowPaymentMode = borrow.getPaymentMode();//借款标的还款方式
		//借款申请用户id
		Integer borrowApplyUserId = null;
		BorrowApplyVo borrowApply = borrowDao.getBorrowApplyVoById(borrow.getBorrowApplyId());
		if (borrowApply != null) {
			borrowApplyUserId = borrowApply.getUserId();
		}
		//符合借款标条件的投标者
		List<TenderAuto> tenderAutolist = new ArrayList<TenderAuto>();
		borrow.setAmount(borrowAmount);
		borrow.setNotTenderMoney(notTenderMoney);
		//获取所有满足设定自动投标要求的用户
		List<TenderAuto> tenderAutos = tenderAutoDao.autoList(borrow);
		List<TenderOrder> tenderOrders = new ArrayList<TenderOrder>();
		if (tenderAutos != null && tenderAutos.size()>0) {
			for (TenderAuto tenderAuto : tenderAutos){
				if (notTenderMoney <=0) {
					break;
				}
				User user = userDao.getById(tenderAuto.getUserId());
				if (StringUtils.isBlank(user.getDealPassword())) {
					continue;
				}
				//借款标：
				if (!tenderAuto.getPaymentMode().equals(-1) && !tenderAuto.getPaymentMode().equals(borrowPaymentMode)) {
					continue;
				}
				if (borrowApplyUserId != null && borrowApplyUserId.equals(tenderAuto.getUserId())) {
					continue;
				}
				//金额：
				UserAccount userAccount = userAccountDao.getByUserId(tenderAuto.getUserId());
				Double balance = userAccount.getBalance() == null?0d:userAccount.getBalance();
				Double reserveFund = tenderAuto.getReserveFund() == null?0d:tenderAuto.getReserveFund();
				if (borrow.getMin() != null && borrow.getMin()>0d) {
					if (tenderAuto.getMoney() < borrow.getMin()) {
						continue;
					}
				}
				if (borrow.getMax() != null && borrow.getMax()>0d) {
					if (tenderAuto.getMoney() > borrow.getMax()) {
						continue;
					}
				}
/*				if (balance < borrowAmount) {
					continue;
				}*/
				if (balance - reserveFund < tenderAuto.getMoney()) {
					continue;
				}
				if (notTenderMoney < tenderAuto.getMoney()) {
					continue;
				}
				tenderAutolist.add(tenderAuto);
				borrowAmount = borrowAmount - tenderAuto.getMoney();//借款标借款金额递减
				notTenderMoney = notTenderMoney - tenderAuto.getMoney();//剩余可投金额递减
				balance = balance - tenderAuto.getMoney();//用户可用余额递减
				
				TenderOrder tenderOrder = new TenderOrder();
				TenderOrder t = tenderOrderDao.selectByPrimaryKey(tenderAuto.getOrderId());
				if (t != null) {
					tenderOrder.setId(t.getId());
					tenderOrder.setOrder(t.getOrder());
					tenderOrders.add(tenderOrder);
				}
			}
		}
		if (tenderAutolist != null && tenderAutolist.size()>0) {
			//将符合规则的自动投标者批量添加userTender
			for (TenderAuto tenderAuto : tenderAutolist) {
				UserTender userTender = new UserTender();
				userTender.setUserId(tenderAuto.getUserId());
				userTender.setBorrowId(borrowId);
				userTender.setChanges("N");
				userTender.setRepayFinish("N");
				userTender.setAmount(tenderAuto.getMoney());
				userTender.setCreateTime(new Date());
				userTender.setTerminal("PC");
				userTender.setIsAuto("Y");
				userTender.setCode(BaseUtil.generateCode(BaseUtil.TOUZI));
				tenderService.saveOrUpdateUserTender(userTender);
				//赠送积分
				if (userTender.getId() != null) {
					//投资金额转化积分比率
					int temp=100;
					SystemConfig configList=systemService.listSystemConfig();
					/*if(configList!=null && configList.size()>0){
						temp=configList.get(0).getAmount();
					}*/
					int score=(int)(tenderAuto.getMoney()/temp);
					UserAccount userAccount = userAccountService.getByUserId(tenderAuto.getUserId());
					if(score>=1){
						userAccount.setScore(userAccount.getScore()+score);
						MemberLevel level=memberService.getLevelByAmount(userAccount.getScore()+score);
						if(level!=null){
							userAccount.setLevel(level.getId());
						}
						userAccountService.saveOrUpdate(userAccount);
						//记录积分流水
						ScoreRecord scoreRecord = new ScoreRecord();
						scoreRecord.setUserId(tenderAuto.getUserId());
						scoreRecord.setOptType("in");
						scoreRecord.setAmount(score);
						scoreRecord.setWay("投资获得积分");
						scoreRecord.setCreateTime(new Date());
						scoreRecord.setTerminal("PC");
						scoreRecordService.saveScoreRecord(scoreRecord);	
					}
				}
			}
		}
		//更新已经自动投标用户的排序号(后投的排在前面，先投的排在后面)
		//1.将已经自动投标者排序号降序排列
		if (tenderOrders != null && tenderOrders.size()>0) {
			Collections.sort(tenderOrders, new Comparator<TenderOrder>(){  
	            public int compare(TenderOrder o1, TenderOrder o2) {  
	                if(o1.getOrder() < o2.getOrder()){  
	                    return 1;  
	                }  
	                return -1;  
	            }  
	        });   
			//2.降序排列后，第一个为最后自动投标者，排在前面;其余依次排
			if (tenderOrders.get(0) != null) {
				int maxOrder = tenderOrders.get(0).getOrder();
				for (int i = 0; i < tenderOrders.size(); i++) {
					tenderOrders.get(i).setOrder(maxOrder+i+1);
				}
			}
			tenderOrderDao.batchUpdate(tenderOrders);
		}
				
		return tenderAutolist;
	}
	
	public TenderAuto selectById(Integer id){
		return tenderAutoDao.selectByPrimaryKey(id);
	}
	
	public TenderOrderVo selectByUserId(Integer userId){
		return tenderAutoDao.selectByUserId(userId);
	}
	
	public TenderOrder selectByOrderId(Integer id){
		return tenderOrderDao.selectByPrimaryKey(id);
	}
	
	public Integer lastId(){
		return tenderOrderDao.lastId();
	}
}
